package com.pkk.penguin.util.image.support.make;

import com.pkk.components.util.util.FileHelper;
import com.pkk.components.util.util.StringHelper;
import com.pkk.penguin.uti.oss.util.PenguinOssUploadUtil;
import com.pkk.penguin.util.image.support.dto.ImageTextAttri;
import com.pkk.penguin.util.image.support.enums.ImageTypeEnum;
import com.pkk.penguin.util.image.support.utils.Graphics2DDrawUtil;
import com.pkk.penguin.util.image.support.utils.ImageStreamUtil;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.List;
import javax.imageio.ImageIO;
import org.apache.commons.lang3.StringUtils;

/**
 * @description: 图片增加文本
 * @author: peikunkun
 * @create: 2018-09-24 16:21
 **/
public class ImageEncodeText {

  /**
   * 图片宽度
   */
  public Integer srcImgWidth;
  /**
   * 图片高度
   */
  public Integer srcImgHeight;

  /**
   * 渲染图片记数
   */
  private Integer countNum = 1;


  /**
   * 是否上传文章
   */
  private static final boolean IS_UPLOAD_OSS_TRUE = true;
  private static final boolean IS_UPLOAD_OSS_FALSE = false;


  /**
   * @param srcImg 源图片
   */
  public void makeImageText(InputStream srcImg, OutputStream targetImg, List<ImageTextAttri> imageTextAttris) {
    makeImage(srcImg, targetImg, imageTextAttris);
  }

  public void makeImageText(URL srcImg, OutputStream targetImg, List<ImageTextAttri> imageTextAttri) {
    makeImage(srcImg, targetImg, imageTextAttri);
  }


  /**
   * @param srcImg 源图片
   */
  public String makeImageText(InputStream srcImg, List<ImageTextAttri> imageTextAttris) {
    return makeImageTextHandle(srcImg, "", imageTextAttris, IS_UPLOAD_OSS_FALSE);
  }

  /**
   * @Description：合成图片
   * @Param: [srcImg, imageTextAttri]
   * @return: java.lang.String
   * @Author: peikunkun
   * @Date: 2019/11/19 0019 下午 6:23
   */
  public String makeImageText(URL srcImg, List<ImageTextAttri> imageTextAttri) {
    BufferedImage read = null;
    try {
      read = ImageIO.read((URL) srcImg);
    } catch (IOException e) {
      e.printStackTrace();
      return "";
    }
    return makeImageTextHandle(ImageStreamUtil.bufferedImageToInputStream(read), "", imageTextAttri,
        IS_UPLOAD_OSS_FALSE);
  }


  /**
   * @Description:处理图片
   * @Param: [srcImg, imageTextAttri]
   * @return: java.lang.String
   * @Author: peikunkun
   * @Date: 2019/11/9 0009 下午 3:51
   */
  public String makeImageTextToOss(URL srcImg, String fileFullPath, List<ImageTextAttri> imageTextAttri) {
    BufferedImage read = null;
    try {
      read = ImageIO.read((URL) srcImg);
    } catch (IOException e) {
      e.printStackTrace();
      return "";
    }
    return makeImageTextHandle(ImageStreamUtil.bufferedImageToInputStream(read), fileFullPath, imageTextAttri,
        IS_UPLOAD_OSS_TRUE);
  }


  /**
   * @Description:处理图片
   * @Param: [srcImg, imageTextAttri]
   * @return: java.lang.String
   * @Author: peikunkun
   * @Date: 2019/11/9 0009 下午 3:51
   */
  public String makeImageTextToOss(InputStream srcImg, String fileFullPath, List<ImageTextAttri> imageTextAttri) {
    return makeImageTextHandle(srcImg, fileFullPath, imageTextAttri, IS_UPLOAD_OSS_TRUE);
  }


  /**
   * @Description:处理图片
   * @Param: [srcImg, imageTextAttri]
   * @return: java.lang.String
   * @Author: peikunkun
   * @Date: 2019/11/9 0009 下午 3:51
   */
  public String makeImageTextToOss(URL srcImg, List<ImageTextAttri> imageTextAttri) {
    BufferedImage read = null;
    try {
      read = ImageIO.read(srcImg);
    } catch (IOException e) {
      e.printStackTrace();
      return "";
    }
    return makeImageTextHandle(ImageStreamUtil.bufferedImageToInputStream(read), "", imageTextAttri,
        IS_UPLOAD_OSS_TRUE);
  }


  /**
   * @Description:处理图片
   * @Param: [srcImg, imageTextAttri]
   * @return: java.lang.String
   * @Author: peikunkun
   * @Date: 2019/11/9 0009 下午 3:51
   */
  public String makeImageTextToOss(InputStream srcImg, List<ImageTextAttri> imageTextAttri) {
    return makeImageTextHandle(srcImg, "", imageTextAttri, IS_UPLOAD_OSS_TRUE);
  }


  /**
   * @Description:处理类的基础属性
   * @Param: [srcImg]
   * @return: com.pkk.penguin.util.image.support.make.ImageEncodeText
   * @Author: peikunkun
   * @Date: 2019/11/9 0009 下午 5:02
   */
  public ImageEncodeText build(InputStream srcImg) {
    return handleBuild(srcImg);
  }

  /**
   * @Description:处理类的基础属性
   * @Param: [srcImg]
   * @return: com.pkk.penguin.util.image.support.make.ImageEncodeText
   * @Author: peikunkun
   * @Date: 2019/11/9 0009 下午 5:03
   */
  public ImageEncodeText build(URL srcImg) {
    return handleBuild(srcImg);
  }

  /**
   * @Description: 处理类的基础属性
   * @Param: [srcImg]
   * @return: com.pkk.penguin.util.image.support.make.ImageEncodeText
   * @Author: peikunkun
   * @Date: 2019/11/9 0009 下午 5:02
   */
  private ImageEncodeText handleBuild(Object srcImg) {
    InputStream inputStream = null;
    if (srcImg instanceof URL) {
      BufferedImage read = null;
      try {
        read = ImageIO.read((URL) srcImg);
      } catch (IOException e) {
        e.printStackTrace();
      }
      inputStream = ImageStreamUtil.bufferedImageToInputStream(read);
    } else if (srcImg instanceof InputStream) {
      inputStream = (InputStream) srcImg;
    }
    try {
      //文件转化为图片
      Image srcImage = ImageIO.read(inputStream);
      //获取图片的宽
      this.srcImgWidth = srcImage.getWidth(null);
      //获取图片的高
      this.srcImgHeight = srcImage.getHeight(null);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return this;
  }


  /**
   * @Description: 处理文件路径
   * @Param: [srcImg, saveFileFullPath, imageTextAttri]
   * @return: java.lang.String
   * @Author: peikunkun
   * @Date: 2019/11/9 0009 下午 3:49
   */
  private String makeImageTextHandle(InputStream srcImg, String saveFileFullPath, List<ImageTextAttri> imageTextAttri,
      boolean isUploadOss) {
    String ossPath = "";
    String fileFullPath = "";
    //是否临时产生的文件路劲
    boolean isTempFullPath = false;
    FileOutputStream fileOutputStream = null;
    try {
      if (StringUtils.isBlank(saveFileFullPath)) {
        fileFullPath = System.getProperty("user.dir").concat(System.getProperty("file.separator")).concat("temp")
            .concat(System.getProperty("file.separator")).concat(StringHelper.randomStr(16)).concat(".png");
        isTempFullPath = true;
      }

      boolean newFile = true;
      if (!FileHelper.exists(fileFullPath)) {
        newFile = FileHelper.createNewFile(fileFullPath);
      }

      if (!newFile) {
        throw new IOException("FILE CREATION FAILED;THE PATH IS " + fileFullPath);
      }

      File file = new File(fileFullPath);
      fileOutputStream = new FileOutputStream(file);
      makeImage(srcImg, fileOutputStream, imageTextAttri);
      //是否上传文章
      if (isUploadOss) {
        ossPath = PenguinOssUploadUtil.uploadFileLocal(fileFullPath);
      } else {
        ossPath = fileFullPath;
      }
      //是临时文章并且不是文章上传
      if (!isTempFullPath && isUploadOss) {
        FileHelper.deleteFile(fileFullPath);
      }
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      try {
        fileOutputStream.flush();
      } catch (IOException e) {
        e.printStackTrace();
      }
      try {
        fileOutputStream.close();
      } catch (IOException e) {
        e.printStackTrace();
      }

    }
    return ossPath;
  }


  /**
   * @Description: 处理图片的操作
   * @Param: [srcImg, targetImg, imageTextAttris]
   * @return: java.io.OutputStream
   * @Author: peikunkun
   * @Date: 2019/11/8 0008 上午 11:08
   */
  private void makeImage(Object srcImg, OutputStream targetImg, List<ImageTextAttri> imageTextAttris) {
    InputStream inputStream = null;
    BufferedImage bufImg = null;
    if (srcImg instanceof URL) {
      BufferedImage read = null;
      try {
        read = ImageIO.read((URL) srcImg);
      } catch (IOException e) {
        e.printStackTrace();
      }
      inputStream = ImageStreamUtil.bufferedImageToInputStream(read);
    } else if (srcImg instanceof InputStream) {
      inputStream = (InputStream) srcImg;
    }
    try {
      //文件转化为图片
      Image srcImage = ImageIO.read(inputStream);
      //获取图片的宽
      srcImgWidth = srcImage.getWidth(null);
      //获取图片的高
      srcImgHeight = srcImage.getHeight(null);

      bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
      for (ImageTextAttri imageTextAttri : imageTextAttris) {
        bufImg = iterImage(srcImage, imageTextAttri, bufImg);
      }
      // 输出图片
      ImageIO.write(bufImg, ImageTypeEnum.PNG.getImageType(), targetImg);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        bufImg.flush();
        targetImg.flush();
        targetImg.flush();
        targetImg.close();
        inputStream.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }


  /**
   * @Description: 增加水印
   * @Param: [imageTextAttri, bufferedImage]
   * @return: java.awt.image.BufferedImage
   * @Author: peikunkun
   * @Date: 2019/11/8 0008 上午 11:05
   */
  private BufferedImage iterImage(Image srcImage, ImageTextAttri imageTextAttri, BufferedImage bufferedImage) {
    // 加水印
    Graphics2D g = bufferedImage.createGraphics();
    if (countNum == 1) {
      countNum++;
      g.drawImage(srcImage, 0, 0, srcImgWidth, srcImgHeight, null);
    } else {
      g.drawImage(bufferedImage, 0, 0, srcImgWidth, srcImgHeight, null);
    }

    //根据图片的背景设置水印颜色
    g.setColor(imageTextAttri.getContentColor().getColor());
    //设置字体
    g.setFont(imageTextAttri.getFont());

    //换行画出水印
    Graphics2DDrawUtil
        .drawString(g, imageTextAttri.getContent(), imageTextAttri.getLineHeight(), imageTextAttri.getMaxWidth(),
            imageTextAttri.getMaxLine(), imageTextAttri.getLeft(), imageTextAttri.getTop(), imageTextAttri.isTrim(),
            imageTextAttri.isLineIndent());

    //g.drawString(imageTextAttri.getContent(), imageTextAttri.getOffSetX(), imageTextAttri.getOffSetY());
    g.dispose();
    return bufferedImage;
  }


  /**
   * @Description: 获取文字长度
   * @Param: [content:文字, g]
   * @return: int
   * @Author: peikunkun
   * @Date: 2018/9/24 0024 下午 4:46
   */
  private int getWatermarkLength(String content, Graphics2D g) {
    return g.getFontMetrics(g.getFont()).charsWidth(content.toCharArray(), 0, content.length());
  }
}
